<html>
<head><meta charset="utf-8"><title>Dealing with lifetimes · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html">Dealing with lifetimes</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="248689526"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248689526" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248689526">(Aug 07 2021 at 02:12)</a>:</h4>
<p>I have a problem with lifetimes that I'm having a bit of trouble working out. This isn't compiler specific, but I'm working on the compiler, so...</p>
<p>My code looks like this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">impl</span><span class="o">&lt;'</span><span class="na">a</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">hir</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Visitor</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">ItemLowerer</span><span class="o">&lt;'</span><span class="na">a</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">hir</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="nb">_</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">visit_item</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">item</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="nc">Item</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">hir_item</span><span class="w"> </span>: <span class="nc">hir</span>::<span class="n">Item</span><span class="o">&lt;'</span><span class="na">hir</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">lctx</span><span class="p">.</span><span class="n">with_hir_id_owner</span><span class="p">(</span><span class="n">item</span><span class="p">.</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">lctx</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">lctx</span><span class="p">.</span><span class="n">without_in_scope_lifetime_defs</span><span class="p">(</span><span class="o">|</span><span class="n">lctx</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="n">lctx</span><span class="p">.</span><span class="n">lower_item</span><span class="p">(</span><span class="n">item</span><span class="p">)</span><span class="w"></span>
<span class="w">            </span><span class="p">})</span><span class="w"></span>
<span class="w">        </span><span class="p">});</span><span class="w"></span>
<span class="o">..</span><span class="p">.</span><span class="w"></span>
</code></pre></div>
<p>For reference, here are the signatures of the relevant functions:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">with_hir_id_owner</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">owner</span>: <span class="nc">NodeId</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="nc">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">Self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">;</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">without_in_scope_lifetime_defs</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="w"></span>
<span class="w">        </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="n">f</span>: <span class="nc">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">LoweringContext</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="nb">_</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">;</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">lower_item</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">i</span>: <span class="kp">&amp;</span><span class="nc">Item</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">hir</span>::<span class="n">Item</span><span class="o">&lt;'</span><span class="na">hir</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
</code></pre></div>
<p>The error message looks like this:</p>
<div class="codehilite"><pre><span></span><code>error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `&#39;hir` due to conflicting requirements
  --&gt; compiler/rustc_ast_lowering/src/item.rs:48:22
   |
48 |                 lctx.lower_item(item)
   |                      ^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the body at 47:49...
  --&gt; compiler/rustc_ast_lowering/src/item.rs:47:49
   |
47 |               lctx.without_in_scope_lifetime_defs(|lctx| {
   |  _________________________________________________^
48 | |                 lctx.lower_item(item)
49 | |             })
   | |_____________^
note: ...so that the types are compatible
  --&gt; compiler/rustc_ast_lowering/src/item.rs:48:22
   |
48 |                 lctx.lower_item(item)
   |                      ^^^^^^^^^^
   = note: expected `&amp;mut LoweringContext&lt;&#39;_, &#39;_&gt;`
              found `&amp;mut LoweringContext&lt;&#39;_, &#39;_&gt;`
note: but, the lifetime must be valid for the lifetime `&#39;_` as defined on the impl at 44:54...
  --&gt; compiler/rustc_ast_lowering/src/item.rs:44:54
   |
44 | impl&lt;&#39;a, &#39;hir&gt; Visitor&lt;&#39;a&gt; for ItemLowerer&lt;&#39;a, &#39;hir, &#39;_&gt; {
   |                                                      ^^
note: ...so that the types are compatible
  --&gt; compiler/rustc_ast_lowering/src/item.rs:46:52
   |
46 |         let hir_item : hir::Item&lt;&#39;hir&gt; = self.lctx.with_hir_id_owner(item.id, |lctx| {
   |                                                    ^^^^^^^^^^^^^^^^^
   = note: expected `&amp;mut LoweringContext&lt;&#39;_, &#39;_&gt;`
              found `&amp;mut LoweringContext&lt;&#39;hir, &#39;_&gt;`

error[E0495]: cannot infer an appropriate lifetime for life
</code></pre></div>
<p>I'm more than a little lost. Probably something obvious, but I've only worked with lifetimes enough to handle simple situations.</p>



<a name="248689599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248689599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248689599">(Aug 07 2021 at 02:14)</a>:</h4>
<p>I know that every experienced rust programmer finds joy in helping newcomers understand how lifetimes work. ;)</p>



<a name="248691496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248691496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248691496">(Aug 07 2021 at 02:55)</a>:</h4>
<p>I'm not sure exactly why, but since the closure in <code>without_in_scope_lifetime_defs</code> has the signature <code>f: impl FnOnce(&amp;mut LoweringContext&lt;'_, '_&gt;) -&gt; T</code> instead of <code>f: impl FnOnce(&amp;mut LoweringContext&lt;'_, 'hir&gt;) -&gt; T</code>, the local second lifetime there (call it <code>'hir2</code>) is shorter than the <code>'hir</code> lifetime, and <code>lctx.lower_item(item)</code> is returning a <code>hir::Item&lt;'hir2&gt;</code> instead of <code>hir::Item&lt;'hir&gt;</code></p>



<a name="248692103"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248692103" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248692103">(Aug 07 2021 at 03:09)</a>:</h4>
<p>AFAICT this is an unnecessary restriction in <code>without_in_scope_lifetime_defs</code> - you should be able to just change the signature and it will still compile. It might be restricted like that for an API reason though</p>



<a name="248692948"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248692948" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248692948">(Aug 07 2021 at 03:29)</a>:</h4>
<p>Thanks! It worked like a charm.</p>



<a name="248693065"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248693065" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248693065">(Aug 07 2021 at 03:31)</a>:</h4>
<p>There's unlikely to be an API reason for it. The function is a module private utility function, and there's only one <code>LoweringContext</code> in any case.</p>



<a name="248693309"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248693309" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248693309">(Aug 07 2021 at 03:37)</a>:</h4>
<p>Actually, even <code>f: impl FnOnce(&amp;mut Self) -&gt; T</code> seems to work (you couldn't have known that though, I don't think I gave you enough information).</p>



<a name="248693641"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248693641" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248693641">(Aug 07 2021 at 03:44)</a>:</h4>
<p>that's probably a better signature anyway</p>



<a name="248693671"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Dealing%20with%20lifetimes/near/248693671" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Dealing.20with.20lifetimes.html#248693671">(Aug 07 2021 at 03:45)</a>:</h4>
<p>Yeah! If nothing else, it's much more readable.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>